{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "#1 美观并正确地书写Python语句\n",
    "\n",
    "###书写的美观性\n",
    "\n",
    "往往问题不仅是美观，还在于程序的可读性："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "testnum = True\n",
    "print testnum\n",
    "testnum = True;print testnum"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###书写的正确性\n",
    "\n",
    "用四空格或一Tab表示缩进。\n",
    "\n",
    "错误缩进："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "IndentationError",
     "evalue": "unexpected indent (<ipython-input-1-ca4e5ad1bc31>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-1-ca4e5ad1bc31>\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m    print \"Value is ,{0}\".format(i)\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unexpected indent\n"
     ]
    }
   ],
   "source": [
    "i = 42\n",
    "    print \"Value is ,{0}\".format(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "正确缩进："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3\n"
     ]
    }
   ],
   "source": [
    "for i in xrange(5):\n",
    "    if i > 3:\n",
    "        break\n",
    "    else:\n",
    "        print i,\n",
    "else:\n",
    "    print \"Expectedly Finished\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#2 Python控制流语法（if/else/for/while等）\n",
    "\n",
    "\n",
    "###2.1 if和else\n",
    "\n",
    "在Python中，标准的if-else或者单if条件语句语法是这样的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "do something\n"
     ]
    }
   ],
   "source": [
    "expression = True\n",
    "\n",
    "if expression:\n",
    "    print \"do something\"\n",
    "else:\n",
    "    print \"do something_else\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "程序员笑话："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n"
     ]
    }
   ],
   "source": [
    "hot = True\n",
    "watermelon = True\n",
    "cnt_steamdumpling = 12\n",
    "if hot & watermelon:\n",
    "    cnt_steamdumpling = 1\n",
    "\n",
    "print cnt_steamdumpling"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运算符有优先级："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Damn...\n"
     ]
    }
   ],
   "source": [
    "yourage = 25\n",
    "had_a_girlfriend = False\n",
    "\n",
    "if yourage > 18 and not had_a_girlfriend:\n",
    "    print \"Damn...\"\n",
    "else:\n",
    "    print \"Ok.\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "多重if-else使用elif："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(￣﹏￣) (￣ˇ￣)\n"
     ]
    }
   ],
   "source": [
    "your_salary = 7000\n",
    "your_location = \"Beijing\"\n",
    "if your_salary > 100000:\n",
    "    print \"(￣︶￣)> []\"\n",
    "elif your_salary >= 25000:\n",
    "    print \"<(￣︶￣)/*\"\n",
    "else:\n",
    "    print \"(￣﹏￣) (￣ˇ￣)\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "书写if else 语句时候也是另一个需要注意缩进的地方\n",
    "\n",
    "如果你在Ipython中书写if-else语句的话，Ipython将在“:”的下一行自动为你缩进，这点非常方便，但是不推荐以下风格的代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "do something\n"
     ]
    }
   ],
   "source": [
    "if True: print \"do something\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2 条件表达式（三元操作符）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "正常的if/else写法，有些臃肿"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "17\n"
     ]
    }
   ],
   "source": [
    "x,y = 111,17\n",
    "if x < y:\n",
    "    smaller = x\n",
    "else:\n",
    "    smaller = y\n",
    "print smaller"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "简洁的三元表达式，Ruby风味"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n"
     ]
    }
   ],
   "source": [
    "x , y = 25,10\n",
    "smaller = x if x < y else y\n",
    "print smaller"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "短路求值写法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "x , y  = 3 , 5\n",
    "smaller =  x < y and x or y # x = a?b:c None,'',0,False\n",
    "print smaller\n",
    "\n",
    "x , y  = 5 , 3\n",
    "smaller =  x < y and x or y\n",
    "print smaller"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "装X失败案例：x被判False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "x , y  = None , 0\n",
    "\n",
    "print x < y\n",
    "\n",
    "smaller =  x > y and x or y\n",
    "print smaller"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###2.3 For循环"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "先介绍range(start,end,step)函数：（生成可迭代序列，Iterable）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
      "[1, 2, 3, 4]\n",
      "[5, 4, 3, 2]\n",
      "xrange(10)\n",
      "0 1 4 9 16 25 36 49 64 81\n"
     ]
    }
   ],
   "source": [
    "print range(10)\n",
    "print range(1,5,1)\n",
    "print range(5,1,-1)\n",
    "print xrange(10)\n",
    "for i in xrange(10):\n",
    "    print i ** 2,\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "s = \"string\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "for循环可以方便的迭代字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "s\n",
      "t\n",
      "r\n",
      "i\n",
      "n\n",
      "g\n"
     ]
    }
   ],
   "source": [
    "for eachletter in s:\n",
    "    print eachletter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python 默认会在每个打印出来的字母后加换行符。\n",
    "\n",
    "如果不需要这个特性，则在语句后加逗号“,”："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "s t r i n g\n"
     ]
    }
   ],
   "source": [
    "for eachletter in s:\n",
    "    print eachletter,"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "####同步取循环索引\n",
    "\n",
    "回忆一下基础语法中介绍的len函数和字符串的切片访问方法，不推荐以下写法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "13\n",
      "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]\n",
      "B  0\n",
      "e  1\n",
      "   2\n",
      "E  3\n",
      "n  4\n",
      "u  5\n",
      "m  6\n",
      "e  7\n",
      "r  8\n",
      "a  9\n",
      "t 10\n",
      "e 11\n",
      "d 12\n"
     ]
    }
   ],
   "source": [
    "a = \"Be Enumerated\"\n",
    "lena = len(a)\n",
    "print lena\n",
    "print range(lena)\n",
    "for eachnum in range(lena):\n",
    "    print \"{0} {1:>2}\".format(a[eachnum],eachnum)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用enumerate方法来同步循环索引："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 B\n",
      "1 e\n",
      "2  \n",
      "4 n\n",
      "6 m\n",
      "7 e\n",
      "8 r\n",
      "10 t\n",
      "11 e\n",
      "12 d\n"
     ]
    }
   ],
   "source": [
    "for idx, element in enumerate(a):\n",
    "    if idx%2==0 or element=='e':\n",
    "        print idx, element   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.4 while语法和奇特的else\n",
    "\n",
    "while语句的形式类似if语句。\n",
    "\n",
    "如果while后面的条件为真，冒号下的代码块就会不断循环执行，直到判断条件变为0或者False.\n",
    "\n",
    "while语句后可以写else语句，如果没被干涉，最终收尾的时候会执行代码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "looping 0\n",
      "1\n",
      "looping 1\n",
      "2\n",
      "looping 2\n",
      "3\n",
      "looping 3\n",
      "4\n",
      "Finite loop\n",
      "looping 0\n",
      "1\n",
      "looping 1\n",
      "2\n",
      "looping 2\n",
      "3\n",
      "looping 3\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "count = 0\n",
    "while count <= 3:\n",
    "    print \"looping {0}\".format(count)\n",
    "    count += 1\n",
    "    print count\n",
    "else:\n",
    "    print \"Finite loop\"\n",
    "\n",
    "count = 0\n",
    "while True:\n",
    "    print \"looping {0}\".format(count)\n",
    "    count += 1\n",
    "    print count\n",
    "    if count > 3:\n",
    "        break\n",
    "else:\n",
    "    print \"Broken loop\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "while-else的组合有些奇特，补充一个更奇特的组合：for-else。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "Finished\n",
      "====================\n",
      "0\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "for i in xrange(3):\n",
    "    print i\n",
    "else:\n",
    "    print \"Finished\"\n",
    "\n",
    "print \"=\" * 20\n",
    "\n",
    "for i in xrange(3):\n",
    "    if i > 1:\n",
    "        break\n",
    "    print i\n",
    "else:\n",
    "    print \"Finished\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###2.5 干涉循环行为（break/continue/pass）\n",
    "\n",
    "* pass：不做任何事。\n",
    "* continue：告诉 Python 跳过当前循环块中的剩余语句，继续进行下一轮循环。\n",
    "* break：结束当前循环来跳转到下个语句。\n",
    "\n",
    "这三个语句有时和if语句一块搭配使用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0\n",
      "0.5\n",
      "0.25\n"
     ]
    }
   ],
   "source": [
    "def foo():\n",
    "    pass\n",
    "\n",
    "a = [1, 0, 2, 4]\n",
    "for element in a:\n",
    "    if element == 0:\n",
    "        continue\n",
    "    print 1. / element"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1+2j)\n",
      "(-2+4j)\n",
      "(-11-16j)\n",
      "(-134+352j)\n"
     ]
    }
   ],
   "source": [
    "z = 1 + 1j\n",
    "while True:\n",
    "    if abs(z) > 100:\n",
    "        break\n",
    "    z = z ** 2 + 1\n",
    "    print z"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#3 Python基本数据结构详述"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python中内置了四种数据结构—列表，元组，字典和集合，用三种不同的括号就可以表示他们。\n",
    "\n",
    "list（列表）是处理一组有序项目的数据结构，列表的元素需要以[](中括号）来包裹，元素的个数和值可以改变。\n",
    "\n",
    "tuple的元素以() 来包裹，元组可以看作只读的列表。\n",
    "\n",
    "列表和元组都使用切片方法来访问元素，数字索引从0开始计数。\n",
    "\n",
    "通过切片（[]和[:]),列表和元组可以得到子集。列表的子集是列表，元组切片后结果还是元组（不可改变)。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###3.1 List 列表（可变类型）\n",
    "\n",
    "列表的定义可以直接使用方括号扩住数据。\n",
    "\n",
    "熟悉的切片规则[start,end,step]："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "red white\n",
      "['green', 'black']\n",
      "['red', 'blue', 'green'] ['red', 'green', 'white']\n"
     ]
    }
   ],
   "source": [
    "L = ['red','blue','green','black','white']\n",
    "print isinstance(L,list)\n",
    "print L[0],L[-1]\n",
    "print L[2:4]\n",
    "print L[:3],L[::2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "作为可变类型中的一种，列表可以直接修改："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4371170728 4371170728\n",
      "['red', 'blue', 'Ruby', 'sapphire', 'white', 42, False]\n"
     ]
    }
   ],
   "source": [
    "M = ['red','blue','green','black','white',42,True]  # 列表中可以包含不同类型的元素\n",
    "M[2:4] = ['Ruby','sapphire']\n",
    "N = M\n",
    "print id(M),id(N)\n",
    "M[-1] = False                                     # 可以通过切片修改\n",
    "print N                                           # 可变类型的特点，不直接操作N，N内容被改变"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8 9] <type 'numpy.ndarray'> int64\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "a = np.array(range(10))\n",
    "print a,type(a),a.dtype\n",
    "import scipy as sp\n",
    "import statsmodels as smodel\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "对于同一类型的数值数据，推荐使用运行效率更高的numpy来进行处理。\n",
    "\n",
    "对于列表，我们可以使用多种方法来进行操纵："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['red', 'blue', 'green', 'black', 'white']\n",
      "['red', 'blue', 'green', 'black', 'white', 'pink']\n",
      "['red', 'blue', 'green', 'black', 'white'] pink\n",
      "['blue', 'green', 'black', 'white'] red\n",
      "['blue', 'green', 'black', 'white', 'pink', 'purple', 'purple']\n",
      "['blue', 'green', 'black', 'white', 'pink', 'purple']\n",
      "pink\n"
     ]
    }
   ],
   "source": [
    "LM = ['red','blue','green','black','white']\n",
    "print LM\n",
    "LM.append('pink')\n",
    "print LM # 列表尾部添加一个元素\n",
    "popped = LM.pop()# 删除并返回列表最后一个元素\n",
    "print LM,popped\n",
    "#试试LM.pop(0)\n",
    "popped2 = LM.pop(0)\n",
    "print LM,popped2\n",
    "LM.extend(['pink','purple','purple'])       # 讲extend后的序列添加到列表中，extend后的内容应该是可迭代的\n",
    "print LM\n",
    "LM.remove('purple')                       # 删除指定值的一个元素\n",
    "print LM\n",
    "print popped"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['blue', 'green', 'black', 'white', 'pink', 'purple']\n",
      "<built-in method reverse of list object at 0x1083ca320>\n",
      "['blue', 'green', 'black', 'white', 'pink', 'purple']\n",
      "['blue', 'green', 'black', 'white', 'pink', 'purple', 'blue', 'green', 'black', 'white', 'pink', 'purple']\n",
      "['blue', 'green', 'black', 'white', 'pink', 'purple', 'blue', 'green', 'black', 'white', 'pink', 'purple']\n"
     ]
    }
   ],
   "source": [
    "print LM[::-1]\n",
    "LL = LM.reverse   #此时已经调用完原地翻转列表方法\n",
    "LL()\n",
    "print LL\n",
    "print LM\n",
    "print LM*2       #也可以像字符串一样用*方法\n",
    "print LM+LM      #也可以像字符串一样用+方法，但+方法不能直接增加元素。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['red', 'blue', 'Ruby', 'sapphire', 'white', 42, False]\n",
      "[False, 42, 'Ruby', 'blue', 'red', 'sapphire', 'white']\n",
      "['red', 'blue', 'Ruby', 'sapphire', 'white', 42, False]\n",
      "[False, 42, 'Ruby', 'blue', 'red', 'sapphire', 'white']\n"
     ]
    }
   ],
   "source": [
    "#LL_law = M.sor\n",
    "#M.sort()\n",
    "#print M\n",
    "#print LL_law\n",
    "print M\n",
    "Mnew = sorted(M)\n",
    "print M\n",
    "M.sort()\n",
    "print M"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "判断某个元素是否在列表中，可以使用in 方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "Ok\n"
     ]
    }
   ],
   "source": [
    "LL_law = ['red', 'blue', 'Ruby', 'sapphire', 'white', 42, False]\n",
    "my_precious = \"silmarils\"\n",
    "print my_precious in LL_law\n",
    "if \"Ruby\" in LL_law:\n",
    "    print \"Ok\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "不爽字符串很久了？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['M', 'u', 'k', 'a', 't', 's', 'u', 'k', 'u']\n",
      "Mukatsuku\n"
     ]
    }
   ],
   "source": [
    "string = 'Mukatsuku'\n",
    "ls_str = list(string)\n",
    "print ls_str\n",
    "print ''.join(ls_str)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###3.2 Tuple 元组（不可变类型）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "元组的元素之间以逗号隔开，可以用小括号包裹（推荐）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<type 'tuple'> <type 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "war3 = ('Orc','Humans','Undead','Night Elves')\n",
    "heros = 'Blade Master','Farseer','Tauren Chieftain','Shadow Hunter'\n",
    "\n",
    "print type(war3),type(heros)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果需要明确地删除一个列表或者元组，使用del："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Orc', 'Humans', 'Undead', 'Night Elves')\n"
     ]
    }
   ],
   "source": [
    "war3copy = war3\n",
    "print war3copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Humans\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "'tuple' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-51-39c69d1512f2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0mwar3copy\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mwar3copy\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Trans_Humans\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "print war3copy[1]\n",
    "war3copy[1]=\"Trans_Humans\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "和列表类似，元组同样支持+、*、和 in 方法。\n",
    "\n",
    "折衷方案使用“可变”元组："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(42, False, [False], (-203+1j))\n",
      "[42, False, [False], (-203+1j)]\n"
     ]
    }
   ],
   "source": [
    "t = (42,False,[True],-203+1j)\n",
    "t[2][0] = False\n",
    "print t\n",
    "print list(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###3.3 Set 集合（可变类型）与Frozenset 冻结集合（不可变类型）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用花括号来定义，用集合操作来进行运算，用set或者frozenset转化其他序列。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "war3 = ('Orcs','Humans','Undead','Night Elves')\n",
    "Lord_of_ring = ('Ainur','Dragons','Dwarves','Elves','Ents','Hobbits','Humans','Orcs')\n",
    "test_set = set(war3)\n",
    "train = set(Lord_of_ring)\n",
    "ya_test_set = {'Orcs','Humans','Undead','Night Elves'}\n",
    "print 'Orcs' in test_set\n",
    "print 'Orcs' in train\n",
    "print 'Orcs' in ya_test_set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于单个集合内的操作对set而言很方便："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set(['Xmen', 'Undead', 'Humans', 'Orcs', 'Night Elves'])\n",
      "set(['Undead', 'No.17', 'No.16', 'No.18', 'Humans', 'Orcs', 'Night Elves', 'Xmen'])\n",
      "set(['Undead', 'Humans', 'Orcs', 'Night Elves'])\n"
     ]
    }
   ],
   "source": [
    "test_set.add('Xmen')\n",
    "print test_set\n",
    "test_set.update(['No.16','No.17','No.18'])\n",
    "print test_set\n",
    "for item in ['Xmen','No.16','No.17','No.18']:\n",
    "    test_set.remove(item)\n",
    "print test_set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "不可变类型frozenset："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'test_set' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-13-14a6fa50a9f5>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mftest\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfrozenset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtest_set\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0mftest\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mftest\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Xmen'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'test_set' is not defined"
     ]
    }
   ],
   "source": [
    "ftest = frozenset(test_set)\n",
    "print ftest\n",
    "ftest.add('Xmen')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合之间的所有基本操作，对于set和frozenset都适用。\n",
    "\n",
    "我们来验证两个集合论公式：\n",
    "\n",
    "$A \\hat{} B = (A \\backslash B) \\cup (B \\backslash A)$\n",
    "\n",
    "$A \\hat{} B = (A \\cup B) \\backslash ( A \\cap B)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "False\n",
      "False\n",
      "set(['Humans', 'Orcs'])\n",
      "set(['Undead', 'Hobbits', 'Dwarves', 'Humans', 'Orcs', 'Night Elves', 'Dragons', 'Ents', 'Ainur', 'Elves'])\n",
      "set(['Hobbits', 'Dwarves', 'Dragons', 'Ents', 'Ainur', 'Elves'])\n",
      "set(['Undead', 'Hobbits', 'Dwarves', 'Night Elves', 'Dragons', 'Ents', 'Ainur', 'Elves'])\n",
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print test_set==train   #判断是否相等\n",
    "print test_set<train    #判断是否是子集\n",
    "print test_set>train    #判断是否是超集\n",
    "print test_set&train    #求交集\n",
    "print test_set|train    #求并集\n",
    "print train-test_set    #求差集\n",
    "print test_set^train    #求异或\n",
    "\n",
    "print test_set^train == ((train-test_set) | (test_set-train))\n",
    "print test_set^train == (train | test_set) - (train & test_set)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###3.4 Dict 字典（可变数据类型）\n",
    "\n",
    "花括号扩起来，形如{key1:value1,key2:value2,key3:value3}。\n",
    "\n",
    "key是非重复的，value和key一一对应，不需要非重复。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Standard ML', 'C', 'Clojure', 'Scala']\n",
      "['Robin Milner', 'Dennis Ritchie', 'Richy Hickey', 'Martin Odersky']\n",
      "[('Standard ML', 'Robin Milner'), ('C', 'Dennis Ritchie'), ('Clojure', 'Richy Hickey'), ('Scala', 'Martin Odersky')]\n",
      "<dictionary-keyiterator object at 0x104891c58>\n",
      "<dictionary-valueiterator object at 0x104891c58>\n",
      "<dictionary-itemiterator object at 0x104891c58>\n"
     ]
    }
   ],
   "source": [
    "language={\"Scala\":\"Martin Odersky\",\"Clojure\":\"Richy Hickey\",\\\n",
    "          \"C\":\"Dennis Ritchie\",\"Standard ML\":\"Robin Milner\"}\n",
    "print language.keys()      #取得键\n",
    "print language.values()    #取得值\n",
    "print language.items()     #取得键-值对\n",
    "print language.iterkeys()  #取得上述内容的iterable\n",
    "print language.itervalues()\n",
    "print language.iteritems()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "取得某个键对应的值，或者增加一个键值对："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Robin Milner\n",
      "Guido van Rossum\n"
     ]
    }
   ],
   "source": [
    "print language['Standard ML']  \n",
    "language[\"Python\"]=\"Guido van Rossum\" \n",
    "print language['Python']  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "试验一下迭代器："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "key=Python,value=Guido van Rossum\n",
      "key=Standard ML,value=Robin Milner\n",
      "key=C,value=Dennis Ritchie\n",
      "key=Clojure,value=Richy Hickey\n",
      "key=Scala,value=Martin Odersky\n"
     ]
    }
   ],
   "source": [
    "for key in language:\n",
    "    print 'key={0},value={1}'.format(key,language[key])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果要访问某个键，而字典中又不存在这个键和对应的值，将会报错："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'Ruby'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-15-2c7ef4b9ad9c>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0mlanguage\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"Ruby\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m: 'Ruby'"
     ]
    }
   ],
   "source": [
    "print language[\"Ruby\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "所以使用键之前可以先判断其是否在字典中然后再取："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print  language.has_key('Scala')\n",
    "print 'Ruby' in language"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "或者使用一个非常有用的方法：dict.get(key,default=None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "They hardly understand IT\n",
      "Guido van Rossum\n"
     ]
    }
   ],
   "source": [
    "print language.get(\"Haskell\",\"They hardly understand IT\")\n",
    "print language.get(\"Python\",None)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "如果需要删除字典中的某些键  使用del somedict[some_key]；\n",
    "\n",
    "需要直接删除字典本身使用 del somedict即可。\n",
    "\n",
    "向字典中添加键值对，或者根据键更新值非常方便："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Matz is a short form, renew it.\n",
      "Yukihiro Matsumoto is the full name of Ruby's Creator.\n"
     ]
    }
   ],
   "source": [
    "language[\"Ruby\"] = \"Matz\"\n",
    "print language[\"Ruby\"] + \" is a short form, renew it.\"\n",
    "language[\"Ruby\"] = \"Yukihiro Matsumoto\"\n",
    "print language[\"Ruby\"] + \" is the full name of Ruby's Creator.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
